package com.yuuzai.openworld.exceptions;

import java.util.HashMap;
import java.util.Map;

import com.yuuzai.openworld.OpenWorldException;
import com.yuuzai.openworld.OpenWorldObject;

public class Exceptions extends OpenWorldObject {

	private static final String OBJECT_VALUE = "value=";
	private static final String FRAMEWORK_ERROR_FAILED = "Failed in generating framework error.";
	private static final String DEFAULT_EXCEPTION_MESSAGE = "A generic exception was thrown.";

	private static final Map<Class<?>, String> exceptions = new HashMap<Class<?>, String>();
	static {
		exceptions.put(NullConfigurationException.class, "[TECHNICAL] Unexpected null attribute/method return.");
	}

	private static String getMessage(Class<? extends OpenWorldException> exceptionClass) {
		String message = exceptions.get(exceptionClass);
		return (message == null) ? DEFAULT_EXCEPTION_MESSAGE : message;
	}

	public static <T extends OpenWorldException> T getException(Class<T> exceptionClass) {
		if (exceptionClass != null) {
			try {
				T exception = exceptionClass.newInstance();
				exception.setMessage(getMessage(exceptionClass));
				return exception;
			} catch (InstantiationException e) {
				LOGGER.error("", e);
			} catch (IllegalAccessException e) {
				LOGGER.error("", e);
			}
		}
		throw new Error(FRAMEWORK_ERROR_FAILED);
	}

	public static <T extends OpenWorldException> T getException(Class<T> exceptionClass, Object o) {
		if (exceptionClass != null) {
			try {
				T exception = exceptionClass.newInstance();
				exception.setMessage(getMessage(exceptionClass) + OBJECT_VALUE + ((o == null) ? NULL_TO_STRING : o.toString()));
				return exception;
			} catch (InstantiationException e) {
				LOGGER.error("", e);
			} catch (IllegalAccessException e) {
				LOGGER.error("", e);
			}
		}
		throw new Error(FRAMEWORK_ERROR_FAILED);
	}

	private Exceptions() {
	}

}
